import time
from . import chess
from . import score
from . import cache

class Node:
	explorer = None
	def __init__(self, board, board_key=None, height=0):
		self.board = board
		self.board_key = chess.board_key(board) if board_key is None else board_key
		self.height = height
		self.score = None
		self.best_move = None
		self.moves = None

class BoardExplorer:
	def __init__(self, depth):
		self.depth = depth
		self.cache = cache.Cache()
	def run(self, board):
		self.start_time = time.time()
		self.explored = 0
		self.from_cache = 0
		Node.explorer = self
		node = Node(board, height=self.depth)
		node.moves = []
		search(node)
		elapsed = time.time()-self.start_time
		print(f'计算:{self.explored} 深度:{self.depth} 缓存:{self.from_cache} 用时:{round(elapsed*100)/100}')
		return node

def is_terminal(node):
	return (node.height==0) or (not (score.has_king(node.board, 'Red')))

def create_child_nodes(node):
	move_n_board = chess.get_next_moves(node.board)
	children = []
	for move_key, board_key in move_n_board.items():
		board_key = chess.reverse_boardkey(board_key)
		board = chess.board_from_key(board_key)
		child = Node(board, board_key, node.height-1)
		child.heuristic_score = score.red_score(board)
		children.append([move_key, child])
		if not is_terminal(child):
			Node.explorer.cache.score_from_cache(child, node)
	return children

def search(node):
	if is_terminal(node):
		node.score = node.heuristic_score
		return
	Node.explorer.explored += 1
	node.score = -1E6
	children = create_child_nodes(node)
	for move, child in children:
		if child.score is None:
			search(child)
		else:
			Node.explorer.from_cache += 1
		if node.score < -child.score:
			node.score = -child.score
			node.best_move = move
	Node.explorer.cache.add_to_cache(node)
	if node.moves is not None:
		node.moves = [(-child.score, move) for move, child in children]

def print_moves(node, best_moves=10):
	best_move = node.best_move
	moves = sorted(node.moves, key=lambda m: m[0], reverse=True)
	moves = moves[:best_moves]
	print(len(node.moves))
	for s,m in moves:
		print(s,m)
	print(best_move)

explorer = None
def auto_move(board):
	global explorer
	if explorer is None:
		explorer = BoardExplorer(3)
	node = explorer.run(board)
	print_moves(node)
	return None if node.best_move is None else node.best_move[2:]
